import { isEmpty } from "ramda";
import { Suspense, lazy, useMemo } from "react";
import { Navigate, Outlet } from "react-router";

import { Iconify, ReactIcon } from "@/components/icon";
import { CircleLoading } from "@/components/loading";
import { useUserMenu } from "@/store/userStore";
import { flattenTrees } from "@/utils/tree";

import { Tag } from "antd";
import type { Menu } from "#/entity";
import { BasicStatus, MenuType } from "#/enum";
import type { AppRouteObject } from "#/router";
import { getRoutesFromModules } from "../utils";

const ENTRY_PATH = "/src/pages";
const PAGES = import.meta.glob("/src/pages/**/*.tsx");
const loadComponentFromPath = (path: string) => PAGES[`${ENTRY_PATH}${path}`];

/**
 * Build complete route path by traversing from current permission to root
 * @param {Menu} permission - current permission
 * @param {Menu[]} flattenedPermissions - flattened permission array
 * @param {string[]} segments - route segments accumulator
 * @returns {string} normalized complete route path
 */
function buildCompleteRoute(permission: Menu, flattenedPermissions: Menu[], segments: string[] = []): string {
	// Add current route segment
	segments.unshift(permission.route);

	// Base case: reached root permission (parentId = 0)
	if (permission.parentId === "0") {
		return `/${segments.join("/")}`;
	}

	// Find parent and continue recursion
	const parent = flattenedPermissions.find((p) => p.id === permission.parentId);
	if (!parent) {
		console.warn(`Parent permission not found for ID: ${permission.parentId}`);
		return `/${segments.join("/")}`;
	}

	return buildCompleteRoute(parent, flattenedPermissions, segments);
}

// Components
function NewFeatureTag() {
	return (
		<Tag color="cyan" className="!ml-2">
			<div className="flex items-center gap-1">
				<ReactIcon name="fa.FaBell" size={12} />
				<span className="ms-1">NEW</span>
			</div>
		</Tag>
	);
}

// Route Transformers
const createBaseRoute = (permission: Menu, completeRoute: string): AppRouteObject => {
	const { route, label, name, icon, sn, hidden, hideTab, status, frameSrc, newFeature } = permission;

	const baseRoute: AppRouteObject = {
		path: route,
		meta: {
			label,
			name,
			key: completeRoute,
			hideMenu: hidden === "1",
			hideTab,
			disabled: status === BasicStatus.DISABLE,
		},
	};

	if (sn) baseRoute.order = sn;
	if (baseRoute.meta) {
		if (icon) baseRoute.meta.icon = icon;
		if (frameSrc) baseRoute.meta.frameSrc = frameSrc;
		if (newFeature) baseRoute.meta.suffix = <NewFeatureTag />;
	}

	return baseRoute;
};

const createCatalogueRoute = (permission: Menu, flattenedPermissions: Menu[]): AppRouteObject => {
	const baseRoute = createBaseRoute(permission, buildCompleteRoute(permission, flattenedPermissions));

	if (baseRoute.meta) {
		baseRoute.meta.hideTab = true;
	}

	const { parentId, children = [] } = permission;
	if (!parentId) {
		baseRoute.element = (
			<Suspense fallback={<CircleLoading />}>
				<Outlet />
			</Suspense>
		);
	}

	baseRoute.children = transformPermissionsToRoutes(children, flattenedPermissions);

	if (!isEmpty(children)) {
		baseRoute.children.unshift({
			index: true,
			element: <Navigate to={children[0].route} replace />,
		});
	}

	return baseRoute;
};

const createMenuRoute = (permission: Menu, flattenedPermissions: Menu[]): AppRouteObject => {
	const baseRoute = createBaseRoute(permission, buildCompleteRoute(permission, flattenedPermissions));

	if (permission.component) {
		const Element = lazy(loadComponentFromPath(permission.component) as any);

		if (permission.frameSrc) {
			baseRoute.element = <Element src={permission.frameSrc} />;
		} else {
			baseRoute.element = (
				<Suspense fallback={<CircleLoading />}>
					<Element />
				</Suspense>
			);
		}
	}

	return baseRoute;
};

function transformPermissionsToRoutes(menus: Menu[], flattenedMenus: Menu[]): AppRouteObject[] {
	return menus.map((menu) => {
		if (menu.type === MenuType.CATALOGUE) {
			return createCatalogueRoute(menu, flattenedMenus);
		}
		return createMenuRoute(menu, flattenedMenus);
	});
}

// 从环境变量中获取路由模式配置
const ROUTE_MODE = import.meta.env.VITE_APP_ROUTER_MODE;

// 自定义Hook：用于生成权限路由
export function usePermissionRoutes() {
	// 如果路由模式是"module"，直接从模块获取路由
	if (ROUTE_MODE === "module") {
		return getRoutesFromModules();
	}

	// 获取用户菜单信息
	const menus = useUserMenu();
	// 使用useMemo优化性能，仅在permissions变化时重新计算
	return useMemo(() => {
		// 如果没有权限数据，返回空数组
		if (!menus) return [];

		// 将树形结构的权限数据扁平化
		const flattenedPermissions = flattenTrees(menus);

		// 将权限数据转换为路由配置
		return transformPermissionsToRoutes(menus, flattenedPermissions);
	}, [menus]);
}
